<?php

//<editor-fold defaultstate="collapsed" desc="License & Copyright">
/*
 * @license
 */

/**
 *
 * @author Jevgeni Geimanen (jevgeni.geimanen@gmail.com)
 */
//</editor-fold>
class SCComponent extends EventDispatcher implements IJSStruct {

    public function __construct() {
        parent::__construct();
        Site::getInstance()->RegisterComponent($this);
    }

    public function __toString() {
        return $this->Render();
    }

    public function getMainTagName() {
        return "div";
    }

    //<editor-fold defaultstate="collapsed" desc="ControlContainer">
    /**
     * @var Container
     */
    private $_ControlContainer = null;

    /**
     *
     * @return Container
     */
    public function getControlContainer() {
        return $this->_ControlContainer;
    }

    /**
     *
     * @param Container $parent
     * @return ControlContainer 
     */
    public function setParentControl($parent) {
        $this->_ControlContainer = $parent;
        return $this;
    }

    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc="ControlName">
    /**
     * @var string
     */
    private $_ControlName = null;

    /**
     * @return string
     */
    public function getControlName() {
        if (!empty($this->_ControlContainer) && empty($this->_ControlName)) {
            $this->_ControlName = SCComponentHelper::classNameToControlName($this->getClassName());
        }
        return $this->_ControlName;
    }

    /**
     *
     * @param string $name
     * @return ControlName 
     */
    public function setControlName($name) {
        $this->_ControlName = $name;
        return $this;
    }

    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc="ControlFullName">
    /**
     * @var string
     */
    private $_ControlFullName = null;

    /**
     * @smarty id
     * @return string
     */
    public function getControlFullName() {
        if ($this->_ControlFullName === null) {
            if (!$this->getControlName())
                throw new Exception("NO NAME");
            $fname = array();
            $parent = $this;
            do
                $fname[] = $parent->getControlName();
            while (($parent = $parent->getControlContainer()) != null);
            $this->_ControlFullName = join("$", array_reverse($fname));
        }
        return $this->_ControlFullName;
    }

    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Core methods">
    /**
     *
     * @return string 
     */
    public function getUID() {
        return $this->getControlFullName();
    }

    /**
     *
     * @return Component 
     */
    public function Init() {
        return $this;
    }

    /**
     *
     * @return Component 
     */
    public function Create() {
        //$this->CreateLabels();
        return $this;
    }

    /**
     *
     * @return Component 
     */
    public function DispatchEvents() {
        if (sCore::getSite()->getFdatValue('__EVENTER') == $this->getControlFullName()) {
            if (($eventName = sCore::getSite()->getFdatValue('__EVENT')) != null) {
                if ($this->hasEvent($eventName)) {
                    $this->fireEvent($eventName);
                }
            }
        }
        return $this;
    }

    /**
     *
     * @throws Exception 
     * @return string;
     */
    public function Render() {
        if (($res = UITemplater::RenderComponent($this)) != null)
            return $res;
        return $this->RenderTemplateless();
    }

    /**
     *
     * @param boolean $closed
     * @return string 
     */
    protected function RenderOpenTag($closed = false) {
        return "<{$this->getMainTagName()} {$this->RenderMainTagAttributes()}" . ($closed ? "/" : "") . ">";
    }

    /**
     *
     * @return string
     */
    protected function RenderCLoseTag() {
        return "</{$this->getMainTagName()}>";
    }

    /**
     *
     * @return string 
     */
    protected function RenderContents() {
        return "";
    }

    /**
     *
     * @return string
     */
    protected function RenderTemplateless() {
        $has = $this->getHasContents();
        return $this->RenderOpenTag(!$has) . ($has ? $this->RenderContents() . $this->RenderCLoseTag() : "");
    }

    protected function getHasContents() {
        return true;
    }

    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Ajax">
    public function AjaxRender() {
        return $this->AjaxMethodCall('Rerender', json_encode($this->Render()));
    }

    protected function AjaxMethodCall($methodName, $args) {
        echo "sCore.callDOMElementMethod('{$this->getControlFullName()}','{$methodName}',{$args})";
        return $this;
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Labels">
    public static $_Labels = array();

    /**
     *
     * @TODO Caching
     * smarty label
     * @return array 
     */
    public function getLabels() {
        if (!key_exists($c = get_class($this),self::$_Labels)) {
            $res = array();
            $ref = $this->getRefClass();
            while ($ref != null) {
                if (class_exists($class_name = "{$ref->getName()}_Labels")) {
                    $langRef = new ReflectionClass($class_name);
                    $res = array_merge($langRef->getConstants(), $res);
                }
                $ref = $ref->getParentClass();
            }
            self::$_Labels[$c] = $res;
            SCCacheHelper::getInstance()->setObject('SCComponent_Labels',SCComponent::$_Labels);
        }
        return self::$_Labels[$c];
    }

    /**
     * @smarty label
     * @return array
     */
    public function getLabelControls() {
        return $this->getLabels();
        return $this->_LabelControls;
    }

    private $_LabelControls = array();

    private function CreateLabels() {
        $labels = $this->getLabels();
        foreach ($labels as $label) {
            $l = new Label();
            $l->setControlName($label)
                    ->setParentControl($this)
                    ->setText($label);
            $this->_LabelControls[$label] = $l;
        }
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="MainTag">
    /**
     *
     * @param array $attributes 
     */
    protected function CollectMainTagAttributes(&$attributes) {
        $attributes['id'] = $this->getControlFullName();
        return $this;
    }

    /**
     * @smarty mattrs
     * @return string
     */
    public function RenderMainTagAttributes() {
        $attributes = array();
        $this->CollectMainTagAttributes($attributes);
        $res = array();
        foreach ($attributes as $key => $val)
            $res[] = "{$key}='{$val}'";
        return join(" ", $res);
    }

    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="IJSStruct">
    /**
     *
     * @var JSPropertiesCollection 
     */
    private $_JSProperties;

    /**
     *
     * @return array
     */
    public function getJSProperties() {
        if ($this->_JSProperties === null) {
            $this->_JSProperties = new JSPropertiesCollection();
            $this->_JSProperties->setStruct($this);
        }
        return $this->_JSProperties->getProperties();
    }

    /**
     *
     * @param JSPropertyCollection $collection 
     * @return Component
     */
    public function CollectJSProperties(&$collection) {
        return $this;
    }

    // </editor-fold>
}